package com.mms.utsc.smartnet;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.database.SQLException;
import android.os.AsyncTask;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.widget.Toast;

public class DBHandler {

	private ProgressDialog progressDialog;
	private static final int MAX_SLEEP_TIME = 5000;
	private static final String serverURL = "http://www.thebiosa.org/mms/app/fetch.php?";
	private static final boolean[] important = { false, true };
	private LocalDBHandler ldb;
	private Context context;

	public DBHandler(ProgressDialog progressDialog, Context context) {
		this.progressDialog = progressDialog;
		this.ldb = new LocalDBHandler(context);
		this.ldb = this.ldb.open();
		this.context = context;
	}

	void openLocalDBHandler() {
		this.ldb.open();
	}

	void close() {
		this.ldb.close();
	}

	ArrayList<MenuListItem> getCourseList() throws InterruptedException, ExecutionException {
		// TODO*****
		return new CourseListReader().execute().get();
	}

	LocalDBHandler getLocalDBHandler() {
		return this.ldb;
	}

	void updateAnnouncements() throws SQLException, InterruptedException, ExecutionException {
		ldb.createAnnouncementEntries(new AnnouncementListReader().execute().get());
	}

	User verifyLogin(String username, String password) throws InterruptedException, ExecutionException {
		return new UserReader().execute(username, password).get();
	}

	class UserReader extends AsyncTask<String, Integer, User> {

		/**
		 * params[0] = username params[1] = password
		 */
		boolean error = false;
		String errMsg = "";

		@Override
		protected User doInBackground(String... params) {
			User user = null;
			try {
				URL url = new URL(serverURL + "request_type=1&typeId=" + params[0] + "");
				URLConnection fetch = url.openConnection();
				BufferedReader in = new BufferedReader(new InputStreamReader(fetch.getInputStream()));
				String line = in.readLine();
				if (line.equalsIgnoreCase("false")) {
					// invalid username or password
					errMsg = "Invalid username or password.";
					error = true;
					return null;
				}
				JSONObject jo = new JSONObject(line);
				String password = jo.getString("password");
				if (params[1].equals(password)) {
					user = new User(jo.getInt("user_id"), params[0], jo.getString("name"));
				}
			} catch (Exception e) {
				errMsg = "Please check your Internet connection.";
				error = true;
			}
			return user;
		}

		@Override
		protected void onPostExecute(User result) {
			// TODO Auto-generated method stub
			if (!error)
				return;
			super.onPostExecute(result);
			final AlertDialog alert = new AlertDialog.Builder(VarHolder.getCurrContext()).create();
			alert.setButton(AlertDialog.BUTTON_NEGATIVE, "OK", new DialogInterface.OnClickListener() {

				public void onClick(DialogInterface dialog, int which) {
					// TODO Auto-generated method stub
					alert.dismiss();
				}
			});
			alert.setCanceledOnTouchOutside(true);
			alert.setTitle("Login failed");
			alert.setMessage(errMsg);
			alert.show();
		}
	}

	class CourseListReader extends AsyncTask<Void, Integer, ArrayList<MenuListItem>> {

		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			if (progressDialog != null) {
				progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
				progressDialog.setIndeterminate(true);
				progressDialog.setMessage("Loading courses please wait...");
				progressDialog.show();
			}
		}

		protected ArrayList<MenuListItem> doInBackground(Void... params) {
			ArrayList<MenuListItem> courses = new ArrayList<MenuListItem>();
			// courses.add((MenuListItem) new Course());
			// return courses;2
			// private Map <String, String> courses = new <String, String>
			// HashMap();
			try {
				URL url = new URL(serverURL + "request_type=2&typeId=" + VarHolder.getCurrUser().userID + "");
				URLConnection fetch = url.openConnection();
				BufferedReader in = new BufferedReader(new InputStreamReader(fetch.getInputStream()));
				String line;
				while ((line = in.readLine()) != null) {
					JSONArray ja = new JSONArray(line);
					for (int i = 0; i < ja.length(); i++) {
						JSONObject jo = (JSONObject) ja.get(i);
						courses.add(new Course(jo.getInt("course_id"), jo.getString("course_code")));
					}
				}
			} catch (MalformedURLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return courses;

		}

		@Override
		protected void onPostExecute(ArrayList<MenuListItem> result) {
			super.onPostExecute(result);
			if (progressDialog != null) {
				progressDialog.dismiss();
			}
		}

	}

	class AnnouncementListReader extends AsyncTask<Void, Integer, ArrayList<Announcement>> {

		/**
		 * params[0] user.getCourseName params[1] lastid from local db
		 */
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			if (progressDialog != null) {
				progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
				progressDialog.setIndeterminate(true);
				progressDialog.setMessage("Loading notifications please wait...");
				progressDialog.show();
			}
		}

		protected ArrayList<Announcement> doInBackground(Void... params) {
			ArrayList<Announcement> annoucement = new ArrayList<Announcement>();
			// User student = VarHolder.getCurrUser(); // get the current user,
			// so
			// i can find out the
			// courses he/she has
			// String courseName = student.getCourseName();
			try {
				// TODO need a sqlite call to get the last id from local
				// announcement db
				// String lastid = "0";
				String lastid = ldb.getLastAnnouncementID() + "";
				// URL url = new URL(serverURL + "request_type=3&typeId=" +
				// courseName + "&lastId=" + lastid + "");
				Log.i("Last ID", lastid);
				URL url = new URL(serverURL + "request_type=3" + "&lastId=" + lastid);
				URLConnection fetch = url.openConnection();
				BufferedReader in = new BufferedReader(new InputStreamReader(fetch.getInputStream()));
				String line;
				DateFormat formatter = new SimpleDateFormat("yyyy-mm-dd hh:mm:ss");

				while ((line = in.readLine()) != null) {
					JSONArray ja = new JSONArray(line);
					for (int i = 0; i < ja.length(); i++) {
						JSONObject jo = (JSONObject) ja.get(i);
						Announcement newAnn = new Announcement(jo.getInt("noti_id"), formatter.parse(jo.getString("date")), formatter.parse(jo.getString("date_expire")), jo.getString("title"), jo
								.getString("content"), Announcement.AnnouncementType.values()[jo.getInt("type_id") - 1], important[jo.getInt("important")]);
								annoucement.add(newAnn);
								
								Intent notificationIntent = new Intent(context, AnnouncementsViewPager.class);
								PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);

								NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

								Resources res = context.getResources();
								Notification.Builder builder = new Notification.Builder(context);

								builder.setContentIntent(contentIntent).setSmallIcon(R.drawable.biosa_logo_android).setTicker("New BioSA Announcement").setWhen(System.currentTimeMillis()).setAutoCancel(true)
										.setContentTitle(newAnn.getTitleText()).setContentText(newAnn.getContent().substring(0, 15)+"...");
								Notification n = builder.getNotification();

								nm.notify(R.id.tvAnnTitle, n);
					}
				}
			} catch (MalformedURLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ParseException e) {
				// thrown by DateFormat
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return annoucement;
		}

		@Override
		protected void onPostExecute(ArrayList<Announcement> result) {
			super.onPostExecute(result);
			if (progressDialog != null) {
				progressDialog.dismiss();
			}
		}
	}
}
